#include <linux/mutex.h>

#define BYTES_PER_LINE 16
#define ROUTING_LEN 8
#define ROUTING_HEAD_LEN 6
#define MCTP_MAX_PACKET_SIZE 272
#define MAX_CACHE_SIZE 4096
#define BDF_ENTRY_SIZE 3
#define FILE_PATH "/mockdata/IMU/pcie_card.bin"
#define MIN_CTX_LEN 28
#define KEY_LEN 25

#define MCTP_IOC_MAGIC 'm'
#define MCTP_IOC_MAXNR 5
#define MCTP_CMD_CONFIG_TABLE _IOW(MCTP_IOC_MAGIC, 0, int)
#define MCTP_CMD_REINIT _IO(MCTP_IOC_MAGIC, 1)
#define MCTP_CMD_STATISTICS _IOR(MCTP_IOC_MAGIC, 2, int)
#define MCTP_CMD_CONFIG_EID_TABLE _IOW(MCTP_IOC_MAGIC, 3, int)
#define MCTP_CMD_CONFIG_INFO _IOR(MCTP_IOC_MAGIC, 4, int)

static DEFINE_HASHTABLE(file_cache_table, 8);
static DEFINE_MUTEX(cache_table_mutex);

/* 设备ioctrl接口通用参数检查 */
extern s32 comm_ioc_parm_check(u32 cmd, void __user *arg, u32 ioc_magic, u32 ioc_max_nr);

struct mctp_cache {
    char data[MAX_CACHE_SIZE];
    size_t total_len;
    bool is_active;
    struct mutex lock;
};

/* 联合体处理字节序转换 */
union checksum_conv {
    uint32_t value;
    uint8_t bytes[4];
};

/* 队列节点结构 */
struct str_node {
    char *data;                     // 字符串数据
    struct str_node *next;       // 下一个节点指针
};

/* 队列主体结构 */
struct str_queue
{
    struct str_node *head;          // 队列头指针
    struct str_node *tail;          // 队列尾指针
    struct mutex lock;              // 互斥锁
};

/* mctp over pcie协议结构 */
#pragma pack(push, 1)
typedef struct {
    uint8_t pcie_signature;
    uint8_t reserved[1];
    uint16_t requester_id;
    struct {
        uint8_t length_low;
        uint8_t length_high:2;
        uint8_t flags:6;
    } mctp_hdr;
    uint8_t reserved1[2];
    uint8_t msg_tag;
    uint8_t source_eid;
    uint8_t dest_eid;
    uint8_t reserved2[3];
    uint16_t target_id;
    uint8_t msg_type;
} __packed MCTP_BaseHeader;

/* mctp 控制消息扩展头 */
typedef struct {
    uint8_t instance_id:5;
    uint8_t rsvd:3;
    uint8_t command_code;
} MCTP_ControlExtHeader;

/* ncsi消息扩展头 */
typedef struct {
    uint8_t mc_id;
    uint8_t rsvd[2];
    uint8_t iid;
    uint8_t command_type;
    uint8_t channel_id;
} MCTP_NCSIExtHeader;

/* 华为扩展命令结构 */
typedef struct {
    uint8_t huawei_cmd_id;
    uint8_t sub_cmd_id;
    uint8_t extra_cmd;
} Huawei_CmdExtension;

#pragma pack(pop)
/* mctp read函数 */
typedef struct {
    uint8_t msg_type;
    uint16_t requester_eid;
    uint16_t target_eid;
    uint8_t source_eid;
    uint8_t command_code;
    uint8_t msg_tag;
    uint8_t dest_eid;
    uint8_t instance_id;
} __attribute__((packed)) MCTP_control_key;

typedef struct {
    uint8_t msg_type;
    uint16_t requester_eid;
    uint8_t source_eid;
    uint8_t mc_id;
    uint8_t command_type;
    uint8_t hw_cmd;
    uint8_t sub_cmd;
    uint8_t extra_cmd;
    uint16_t target_id;
    uint8_t dest_eid;
    uint8_t channel_id;
    uint8_t iid;
    uint8_t msg_tag;
} __attribute__((packed)) MCTP_ncsi_key;
#pragma pack(push, 1)

typedef struct {
    union {
        __le16 raw_len;
        struct {
            __le16 len_low8 : 8;
            __le16 len_high2 : 2;
            __le16 : 6;
        };
    };

    u8 data[10];

    union {
        u8 flags;
        struct {
            u8 msg_tag : 3;
            u8 TO : 1;
            u8 pkt_seq : 2;
            u8 EOM : 1;
            u8 SOM : 1;
        };
    };
} mctp_header;
#pragma pack(pop)

/* 命令描述结构体 */
struct cmd_entry {
    u32 match_key;
    const char *data_items[4];
    size_t item_count;
};

struct fixed_table_entry {
    char key[KEY_LEN];
    size_t value;
};

// 缓存条目结构
struct file_cache_entry {
    char *path;                    // 文件路径
    char *cache_data;              // 缓存数据
    size_t cache_size;             // 缓存大小
    unsigned long create_time;     // 创建时间（jiffies）
    struct hlist_node hash_node;   // 哈希表节点
};

/* 全局命令表 */
static const struct cmd_entry command_table[] = {
    {0x18000000, {"020000000000000011", "020000000000000022", "020000000000000033"}, 3},
    {0x50010000, {"020000000000000044"}, 1},
    {0x50010200, {"020000000000000055"}, 1},
    {0x50010400, {"020000000000000066"}, 1},
    {0x50010D00, {"020000000000000077", "020000000000000088"}, 2},
};

/* 考虑多包情况 */
const char *valid_keys[] = {
    "020000000000000011",
    "020000000000000022",
    "020000000000000033",
    "020000000000000044",
    "020000000000000055",
    "020000000000000066",
    "020000000000000077",
    "020000000000000088"
};

/* 静态分配固定表, 根据构建key找到对应offset，从而读取数据*/
static const struct fixed_table_entry fixed_table[] = {
    {"00000000000000", 0x00000000},
    {"0000000008000c", 0x00000110},
    {"00030000000b0a", 0x00000220},
    {"0203000b0000000000", 0x00000000},
    {"0203000b0050000e01", 0x00000110},
    {"0203000b0050000100", 0x00000220},
    {"0203000b0018000000", 0x00000330},
    {"020000000000000011", 0x00000440},
    {"020000000000000022", 0x00000550},
    {"020000000000000033", 0x00000660},
    {"0203000b000a000000", 0x00000770},
    {"0203000b0050000100", 0x00000880},
    {"020000000000000044", 0x00000990},
    {"0203000b0050010200", 0x00000AA0},
    {"020000000000000055", 0x00000BB0},
    {"0203000b0050010400", 0x00000CC0},
    {"020000000000000066", 0x00000DD0},
    {"0203000b0050000f00", 0x00000EE0},
    {"0203000b0050000b00", 0x00000FF0},
    {"0203000b0050000d00", 0x00001100},
    {"020000000000000077", 0x00001210},
    {"020000000000000088", 0x00001320},
    {"0203000b0050000500", 0x00001430},
    {"0203000b0050000600", 0x00001540},
    {"0203000b0015000000", 0x00001650},
    {"0203000b0050000a00", 0x00001760},
    {"0203000b0050000c00", 0x00001870}
};